package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicProdDispatchingDetailDAO;
import com.cssy.xxkj.logic.dao.LogicProdDispatchingDetailItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionDispatchingDAO;
import com.cssy.xxkj.logic.dao.LogicProductionDispatchingItemDAO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingDetailCancelDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingDetailDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingDetailItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionDispatchingItemDO;
import com.cssy.xxkj.logic.service.ILogicProdDispatchingDetailService;
import com.cssy.xxkj.logic.service.ILogicProductionCancelService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

/**
 * 生产派工详情业务方法
 * @author zeyong.gui
 *
 */
@Service("logicProdDispatchingDetailService")
public class LogicProdDispatchingDetailServiceImpl implements ILogicProdDispatchingDetailService {
	
	//派工单DAO
	@Resource(name = "logicProductionDispatchingDAO")
	private LogicProductionDispatchingDAO logicProductionDispatchingDAO;
	
	//派工单DAO
	@Resource(name = "logicProductionDispatchingItemDAO")
	private LogicProductionDispatchingItemDAO logicProductionDispatchingItemDAO;
	
	//派工详情单DAO
	@Resource(name = "logicProdDispatchingDetailDAO")
	private LogicProdDispatchingDetailDAO logicProdDispatchingDetailDAO;
	//派工详情单DAO
	@Resource(name = "logicProdDispatchingDetailItemDAO")
	private LogicProdDispatchingDetailItemDAO logicProdDispatchingDetailItemDAO;
	
	//派工详情单DAO
	@Resource(name = "logicProductionCancelService")
	private ILogicProductionCancelService logicProductionCancelService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;

	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicProductionDispatchingDetailDO>  list=logicProdDispatchingDetailDAO.find(scs);
		rs.setRecordCount(logicProdDispatchingDetailDAO.count(scs));
		rs.setResults(list);
		return rs;
	}
	
	@Override
	public List<LogicProductionDispatchingDetailItemDO> findItemListByMap(Map<String, Object> paramMap)
			throws SyBaseException{
		return logicProdDispatchingDetailItemDAO.findListByMap(paramMap);
	}
	
	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		return logicProdDispatchingDetailDAO.deleteLogicProductionDispatchingDetailDOByPrimaryKey(id);
	}

	@Override
	public Integer update(LogicProductionDispatchingDetailDO t, User user)
			throws SyBaseException {
		t.setBizModifyName(user.getName());
		t.setBizModifyDate(new Date());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicProdDispatchingDetailDAO.updateLogicProductionDispatchingDetailDO(t);
	}

	@Override
	public LogicProductionDispatchingDetailDO save(
			LogicProductionDispatchingDetailDO dspingDetail, User user)
			throws SyBaseException {
		dspingDetail.setBizCreatorName(user.getName());
		dspingDetail.setBizCreatorDate(new Date());
		dspingDetail.setBizVersion(Integer.valueOf(1));
		logicProdDispatchingDetailDAO.insertLogicProductionDispatchingDetailDO(dspingDetail);
		return dspingDetail;
	}
	
	/**
	 * 取消派工
	 */
	@Override
	public void detailSave(HttpServletRequest request, LogicProductionDispatchingDetailDO curAP)
			throws SyBaseException{
		try{
			String dataitem = request.getParameter("itemdata");
			String detailId = curAP.getId();
			LogicProductionDispatchingDetailDO detailEntity = logicProdDispatchingDetailDAO.findLogicProductionDispatchingDetailDOByPrimaryKey(detailId);
			if(detailEntity==null){
				throw new SyBaseException("待派工单数据发生改变，请重新提交。");
			}
			//保存派工取消单主表
			LogicProductionDispatchingDetailCancelDO cancelEntity = this.logicProductionCancelService.cancelSave(detailEntity, request);
			//判断是否可以保存
			List<LogicProductionDispatchingDetailItemDO> detailItemList = JSON.parseArray(dataitem, LogicProductionDispatchingDetailItemDO.class);
			//查询该派工单详情单行记录所有取消的和
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("oriId", detailEntity.getId());
			Map<String, BigDecimal> hasCancelMap = logicProductionCancelService.findQueryHasCancelToMap(paramMap); 
			//根据当前的派工明显单主表的oriId，查询该派工单id为oriId的所有详细派工信息
			Map<String, Object> paramTailMap = new HashMap<String, Object>();
			paramTailMap.put("detailId", detailEntity.getId());
			Map<String, LogicProductionDispatchingDetailItemDO> detailItemMap = this.findQueryDetailItemToMap(paramTailMap);
			Map<String, BigDecimal> patchingItemMap = new HashMap<String, BigDecimal>();
			//判断、保存派工取消数据
			for(LogicProductionDispatchingDetailItemDO detailItem : detailItemList){
				if(detailItem==null){
					continue;
				}
				String keyStr = detailEntity.getId()+"_"+detailItem.getZd006MaterialsId()+"_"
					+detailItem.getZd010MaterialsModel()+"_"+detailItem.getZd023MaterialsSize()+"_"
					+detailItem.getZd026MaterialsColor()+"_"+detailItem.getZd027MaterialsQuality()+"_"
					+detailItem.getZd029Process();
				String patchingItemkeyStr = detailEntity.getZd002OriId()+"_"+detailItem.getZd006MaterialsId()+"_"
						+detailItem.getZd010MaterialsModel()+"_"+detailItem.getZd023MaterialsSize()+"_"
						+detailItem.getZd026MaterialsColor()+"_"+detailItem.getZd027MaterialsQuality()+"_"
						+detailItem.getZd029Process();
				//已取消数量
				BigDecimal hsCancelQuantity = BigDecimal.ZERO;
				//总数量(总派工数量)
				BigDecimal sumQuantity = detailItem.getZd013Quantity()==null?BigDecimal.ZERO:detailItem.getZd013Quantity();
				//本次取消数量
				BigDecimal backQuantity = detailItem.getZdTheQuantity()==null?BigDecimal.ZERO:detailItem.getZdTheQuantity();
				if(hasCancelMap==null||hasCancelMap.get(keyStr)==null){
					hsCancelQuantity = backQuantity;
				}else{
					hsCancelQuantity = backQuantity.add(hasCancelMap.get(keyStr));
				}
				//剩余可取消数量
				BigDecimal surpQuantity = sumQuantity.subtract(hsCancelQuantity);
				int compUp = BigDecimal.ZERO.compareTo(surpQuantity);
				if(compUp==1){
					throw new SyBaseException("错误：你本次派工取消数量已大于可取消派工数量。");
				}
				if(patchingItemMap.get(patchingItemkeyStr)==null){
					patchingItemMap.put(patchingItemkeyStr, backQuantity);
				}else{
					patchingItemMap.put(patchingItemkeyStr, backQuantity.add(patchingItemMap.get(patchingItemkeyStr)));
				}
				//保存派工取消单字表
				this.logicProductionCancelService.cancelItemSave(cancelEntity, detailItem, backQuantity);
				//派工详细单的已取消数量
				detailItem.setZd019ReturnQuantity(hsCancelQuantity);
				detailItemMap.put(keyStr, detailItem);
				this.logicProdDispatchingDetailItemDAO.updateLogicProductionDispatchingDetailItemDO(detailItem);
			}
			//判断是否可以删除派工详细单
			boolean canRemove = true;
			for(LogicProductionDispatchingDetailItemDO detailItem : detailItemMap.values()){
				if(detailItem==null||StringUtils.isBlank(detailItem.getId())){
					continue;
				}
				//总派工数
				BigDecimal countQuantity = detailItem.getZd013Quantity()==null?BigDecimal.ZERO:detailItem.getZd013Quantity();
				//总取消数
				BigDecimal backQuantity = detailItem.getZd019ReturnQuantity()==null?BigDecimal.ZERO:detailItem.getZd019ReturnQuantity();
				int compUp = BigDecimal.ZERO.compareTo(countQuantity.subtract(backQuantity));
				if(compUp==-1){
					canRemove = false;
				}
			}
			if(canRemove){
				detailEntity.setRemoved(Long.valueOf(1));
				detailEntity.setBizVersionMark(detailEntity.getBizVersion());
				detailEntity.setBizVersion(detailEntity.getBizVersion()+1);
				logicProdDispatchingDetailDAO.updateLogicProductionDispatchingDetailDO(detailEntity);
			}
			//修改派工单的派工状态
			LogicProductionDispatchingDO patching = logicProductionDispatchingDAO.findLogicProductionDispatchingDOByPrimaryKey(detailEntity.getZd002OriId());
			if(patching==null){
				throw new SyBaseException("派工单数据发生改变，请重新提交。");
			}
			boolean workUp = true;
			Map<String, LogicProductionDispatchingItemDO> dspItemMap = this.findQueryDspItemToMap(patching.getId());
			for(String _keyStr: dspItemMap.keySet()){
				if(StringUtils.isBlank(_keyStr)){
					continue;
				}
				BigDecimal cancelQuantity = patchingItemMap.get(_keyStr);
				if(cancelQuantity==null){
					cancelQuantity = BigDecimal.ZERO;
				}
				LogicProductionDispatchingItemDO dspItem = dspItemMap.get(_keyStr);
				if(dspItem==null||StringUtils.isBlank(dspItem.getId())){
					continue;
				}
				System.out.println(dspItem.getZd023MaterialsSize());
				BigDecimal _theQuantity = dspItem.getZd016ProductionQuantity()==null?BigDecimal.ZERO:dspItem.getZd016ProductionQuantity();
				if(BigDecimal.ZERO.compareTo(_theQuantity)==0){
					continue;
				}
				BigDecimal paiQuantity = _theQuantity.subtract(cancelQuantity);
				int _comUp = BigDecimal.ZERO.compareTo(paiQuantity);
				if(_comUp==1){
					throw new SyBaseException("dispatching item id = "+dspItem.getId()+"总取消的派工数量大于总派工数量");
				}
				BigDecimal _surpQuantity = _theQuantity.subtract(cancelQuantity);
				if(BigDecimal.ZERO.compareTo(_surpQuantity)==-1){
					workUp = false;
				}
				dspItem.setZd016ProductionQuantity(paiQuantity);
				if(BigDecimal.ZERO.compareTo(paiQuantity)==0){
					//表示派工的数量都取消咯，那么退回的数量就应该赋为0；
					dspItem.setZd019ReturnQuantity(BigDecimal.ZERO);
				}else{
					BigDecimal _hasQuantity = dspItem.getZd019ReturnQuantity()==null?BigDecimal.ZERO:dspItem.getZd019ReturnQuantity();
					BigDecimal _sumcelQuantity = _hasQuantity.add(cancelQuantity);
					dspItem.setZd019ReturnQuantity(_sumcelQuantity);
				}
				
				this.logicProductionDispatchingItemDAO.updateLogicProductionDispatchingItemDO(dspItem);
			}
			if(workUp){
				patching.setZd008Billstatus(BillStatusUtil.PRODISPAT_BILL_STATUS_ZERO);
			}else{
				patching.setZd008Billstatus(BillStatusUtil.PRODISPAT_BILL_STATUS_ZONE);
			}
			patching.setBizVersionMark(patching.getBizVersion());
			patching.setBizVersion(patching.getBizVersion()+1);
			this.logicProductionDispatchingDAO.updateLogicProductionDispatchingDO(patching);
		}catch(Exception e){
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	private Map<String, LogicProductionDispatchingItemDO> findQueryDspItemToMap(String patchingId){
		SearchConditions pScs = new SearchConditions();
		pScs.addCondition("zd001ProDispatId", patchingId, SearchCondition.OP_EQUAL);
		pScs.setRemovedProperty(null);
		List<LogicProductionDispatchingItemDO> itemList = this.logicProductionDispatchingItemDAO.find(pScs);
		if(itemList==null||itemList.isEmpty()||itemList.size()==0){
			return new HashMap<String, LogicProductionDispatchingItemDO>();
		}else{
			Map<String, LogicProductionDispatchingItemDO> dspItemMap = new HashMap<String, LogicProductionDispatchingItemDO>();
			for(LogicProductionDispatchingItemDO item : itemList){
				if(item==null||StringUtils.isBlank(item.getId())){
					continue;
				}
				String keyStr = patchingId+"_"+item.getZd006MaterialsId()+"_"
					+item.getZd010MaterialsModel()+"_"+item.getZd023MaterialsSize()+"_"
					+item.getZd026MaterialsColor()+"_"+item.getZd027MaterialsQuality()+"_"
					+item.getZd029Process();
				dspItemMap.put(keyStr, item);
			}
			return dspItemMap;
		}
	}
	
	
	
	/**
	 * 根据派工单的id查询该派工单所有的派工详情单
	 * @param dispatchingId
	 * @return
	 */
	private Map<String, LogicProductionDispatchingDetailDO> findQueryDetailToMap(String dispatchingId){
		SearchConditions detailScs = new SearchConditions();
		detailScs.addCondition("zd002OriId", dispatchingId, SearchCondition.OP_EQUAL);
		List<LogicProductionDispatchingDetailDO> detailList = this.logicProdDispatchingDetailDAO.find(detailScs);
		if(detailList==null||detailList.isEmpty()||detailList.size()==0){
			return new HashMap<String, LogicProductionDispatchingDetailDO>();
		}else{
			Map<String, LogicProductionDispatchingDetailDO> detailMap = new HashMap<String, LogicProductionDispatchingDetailDO>();
			for(LogicProductionDispatchingDetailDO detail : detailList){
				if(detail==null||StringUtils.isBlank(detail.getId())){
					continue;
				}
				String keyStr = dispatchingId+"_"+detail.getId();
				detailMap.put(keyStr, detail);
			}
			return detailMap;
		}
	}
	
	/**
	 * 保存派工详情单
	 */
	@Override
	public LogicProductionDispatchingDetailDO dispatchingDetailSave(
			LogicProductionDispatchingDO patchingEntity,
			HttpServletRequest request) throws SyBaseException {
		try{
			LogicProductionDispatchingDetailDO dspingDetail = new LogicProductionDispatchingDetailDO();
			String detailId = IDCodeTypeUtil.getId();
			String detailCode = syCodeService.getCode(BillTypeConstant.PRODISPATDETAIL,BillTypeConstant.PRODISPATDETAIL,SyCode.DATE_YYMM,5);
			dspingDetail.setId(detailId);
			dspingDetail.setZd001FormCode(detailCode);
			dspingDetail.setZd002SaleId(patchingEntity.getZd002SaleId());
			dspingDetail.setZd002OriId(patchingEntity.getId());
			dspingDetail.setZd002OriCode(patchingEntity.getZd001FormCode());
			dspingDetail.setZd003PiCode(patchingEntity.getZd003PiCode());
			dspingDetail.setZd004CustomerId(patchingEntity.getZd004CustomerId());
			dspingDetail.setZd004CustomerCode(patchingEntity.getZd004CustomerCode());
			dspingDetail.setZd004CustomerName(patchingEntity.getZd004CustomerName());
			dspingDetail.setZd005OrderDate(patchingEntity.getZd005OrderDate());
			dspingDetail.setZd006DeliveryDate(patchingEntity.getZd006DeliveryDate());
			dspingDetail.setZd007SalesMan(patchingEntity.getZd007SalesMan());
			dspingDetail.setZd008Billstatus(BillStatusUtil.PRODISPAT_BILL_STATUS_ZERO);
			dspingDetail.setZd008WorkStatus(BillStatusUtil.PRODISPATDTL_BILL_STATUS_ZERO);
			dspingDetail.setZd009Remark(patchingEntity.getZd009Remark());
			dspingDetail.setZd011WorkShopCode(patchingEntity.getZd011WorkShopCode());
			this.save(dspingDetail, SessionUtil.getUser(request));
			dspingDetail.setId(detailId);
			return dspingDetail;
		}catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	@Override
	public void dispatchingDetailItemSave(LogicProductionDispatchingDetailDO detailEntity,
			LogicProductionDispatchingItemDO patchingItem, BigDecimal theQuantity) throws SyBaseException{
		LogicProductionDispatchingDetailItemDO dspingDetailItem = new LogicProductionDispatchingDetailItemDO();
		dspingDetailItem.setId(IDCodeTypeUtil.getId());
		dspingDetailItem.setZd001DetailId(detailEntity.getId());
		dspingDetailItem.setZd002DetailCode(detailEntity.getZd001FormCode());
		
		dspingDetailItem.setZd003CustomerId(patchingItem.getZd003CustomerId());
		dspingDetailItem.setZd004CustomerCode(patchingItem.getZd004CustomerCode());
		dspingDetailItem.setZd005CustomerName(patchingItem.getZd005CustomerName());
		dspingDetailItem.setZd006MaterialsId(patchingItem.getZd006MaterialsId());
		dspingDetailItem.setZd006MaterialsCode(patchingItem.getZd006MaterialsCode());
		dspingDetailItem.setZd006MaterialsName(patchingItem.getZd006MaterialsName());
		dspingDetailItem.setZd007UseCode(patchingItem.getZdUserCode());
		dspingDetailItem.setZd008UseName(patchingItem.getZdUserName());
		dspingDetailItem.setZd009MaterialsBatch(patchingItem.getZd009MaterialsBatch());
		dspingDetailItem.setZd010MaterialsModel(patchingItem.getZd010MaterialsModel());
		dspingDetailItem.setZd011MaterialsSpec(patchingItem.getZd011MaterialsSpec());
		dspingDetailItem.setZd012MaterialsUnit(patchingItem.getZd012MaterialsUnit());
		dspingDetailItem.setZd013Quantity(theQuantity);
		dspingDetailItem.setZd014Price(patchingItem.getZd013Price());
		dspingDetailItem.setZd015DeliveryDate(patchingItem.getZd014DeliveryDate());
		dspingDetailItem.setZd021MaterialsDescription(patchingItem.getZd021MaterialsDescription());
		dspingDetailItem.setZd022OpenBatch(patchingItem.getZd022OpenBatch());
		dspingDetailItem.setZd023MaterialsSize(patchingItem.getZd023MaterialsSize());
		dspingDetailItem.setZd024MaterialsPicture(patchingItem.getZd024MaterialsPicture());
		dspingDetailItem.setZd025MaterialsAnnex(patchingItem.getZd025MaterialsAnnex());
		dspingDetailItem.setZd026MaterialsColor(patchingItem.getZd026MaterialsColor());
		dspingDetailItem.setZd027MaterialsQuality(patchingItem.getZd027MaterialsQuality());
		dspingDetailItem.setZd028WorkShop(patchingItem.getZd028WorkShop());
		dspingDetailItem.setZd028WorkShopName(patchingItem.getZd028WorkShopName());
		dspingDetailItem.setZd029Process(patchingItem.getZd029Process());
		dspingDetailItem.setZd029ProcessName(patchingItem.getZd029ProcessName());
		//订单数量
		dspingDetailItem.setZd030PlanQuantity(patchingItem.getZd015PlanQuantity());
		//派工数量
		dspingDetailItem.setZd013Quantity(theQuantity);
		this.logicProdDispatchingDetailItemDAO.insertLogicProductionDispatchingDetailItemDO(dspingDetailItem);
	}
	
	private Map<String, LogicProductionDispatchingDetailItemDO> findQueryDetailItemToMap(Map<String, Object> paramMap){
		List<LogicProductionDispatchingDetailItemDO> itemList = this.findItemListByMap(paramMap);
		if(itemList==null||itemList.isEmpty()||itemList.size()==0){
			return new HashMap<String, LogicProductionDispatchingDetailItemDO>();
		}else{
			Map<String, LogicProductionDispatchingDetailItemDO> itemMap = new HashMap<String, LogicProductionDispatchingDetailItemDO>();
			for(LogicProductionDispatchingDetailItemDO detailItem : itemList){
				if(detailItem==null){
					continue;
				}
				String keyStr = paramMap.get("detailId")+"_"+detailItem.getZd006MaterialsId()+"_"
					+detailItem.getZd010MaterialsModel()+"_"+detailItem.getZd023MaterialsSize()+"_"
					+detailItem.getZd026MaterialsColor()+"_"+detailItem.getZd027MaterialsQuality()+"_"
					+detailItem.getZd029Process();
				itemMap.put(keyStr, detailItem);
			}
			return itemMap;
		}
	}
	
	public Map<String, BigDecimal> findQueryDetailHasToMap(Map<String, Object> paramMap){
		List<LogicProductionDispatchingDetailItemDO> detailItemList = logicProdDispatchingDetailItemDAO.findListByMap(paramMap);
		if(detailItemList==null||detailItemList.isEmpty()||detailItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> detailItemMap = new HashMap<String, BigDecimal>();
			for(LogicProductionDispatchingDetailItemDO detailItem : detailItemList){
				if(detailItem==null){
					continue;
				}
				String keyStr = paramMap.get("oriId")+"_"+detailItem.getZd006MaterialsId()+"_"
					+ detailItem.getZd010MaterialsModel()+"_"+detailItem.getZd023MaterialsSize()+"_"
					+ detailItem.getZd026MaterialsColor()+"_"+detailItem.getZd027MaterialsQuality()+"_"
					+ detailItem.getZd029Process();
				BigDecimal zd013Quantity = detailItem.getZd013Quantity()==null?BigDecimal.ZERO:detailItem.getZd013Quantity();
				BigDecimal zdBackQuantity = detailItem.getZd019ReturnQuantity()==null?BigDecimal.ZERO:detailItem.getZd019ReturnQuantity();
				BigDecimal paiGongQuantity = zd013Quantity.subtract(zdBackQuantity);
				if(detailItemMap.get(keyStr)==null){
					detailItemMap.put(keyStr, paiGongQuantity);
				}else{
					detailItemMap.put(keyStr, paiGongQuantity.add(detailItemMap.get(keyStr)));
				}
			}
			return detailItemMap;
		}
	}
	
	@Override
	public LogicProductionDispatchingDetailDO findListById(String id)
			throws SyBaseException {
		return logicProdDispatchingDetailDAO.findLogicProductionDispatchingDetailDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicProdDispatchingDetailDAO.deleteBizRemoved(id);
	}

}
